<?php
/**
 * Created by Zhy
 * User: Zhy
 * Date: 2023/12/12
 * Time: 9:23
 */

namespace app\api\controller;

use app\api\model\PhoneCode AS PhoneCodeModel;
use app\api\model\UUser AS UserModel;
use app\api\validate\CodeCheck;
use app\api\validate\PasswordCheck;
use app\api\validate\PhoneCheck;
use app\api\validate\PwdCheck;
use app\api\validate\UserIdCheck;

class Login extends Base
{
    /**
     * 发送验证码
     * phone     手机号
     * type      发送场景   1 注册   2 登录&忘记密码
     * @return \think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function sendCode(){
        $phone = input('phone');
        $type = input('type') ? input('type') : 1; // 1 注册   2 登录&忘记密码

        $resultPhone = (new PhoneCheck())->goCheck();
        if($resultPhone['status'] == 0) return json(['status' => 0, 'msg' => $resultPhone['msg']]);

        $USER = new UserModel();
        $result = $USER::findUser(['user_phone' => $phone]);
        if($type == 1){
            if($result){
                return  json(['status' => 0, 'msg' => '该手机号已注册']);
            }
        }else{
            if(!$result){
                return  json(['status' => 0, 'msg' => '该手机号尚未注册']);
            }
        }

        $code = GetRandCode();
//        $code = 111111;
        $sendres = YzxSms($code, $phone, ''); // 发送验证码
//        $sendres['code'] = 0; // 发送验证码
        if($sendres['code'] != 0) { // 发送不成功
            return json(['status' => 0, 'msg' => $sendres['msg']]);
        } else {
            $PHONECODE = new PhoneCodeModel();
            $where['phone'] = $phone;
            $hasUser = $PHONECODE::findCode($where);
            if($hasUser){
                $update = [
                    'code'      => $code,
                    'status'    => 0,
                    'time'      => time(),
                    'date_time' => createTime()
                ];
                $res = $PHONECODE::updateCode($where, $update);
            }else{
                $insert = [
                    'phone'     => $phone, // 发送的手机号
                    'code'      => $code, // 验证码
                    'time'      => time(), // 验证码发送的时间戳
                    'date_time' => createTime() // 日期格式
                ];
                $res = $PHONECODE::insertCode($insert);
            }
            if($res) {
                return json(['status' => 200, 'msg' => $code]);
            }else{
                return json(['status' => 0, 'msg' => $this->systemErr]);
            }
        }

    }

    /**
     * 注册
     * phone     手机号
     * code      验证码
     * pwd       密码
     * password  确认密码
     * @return \think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function register(){
        $phone = input('phone');
        $code = input('code');
        $pwd = input('pwd');
        $password = input('password');

        $resultPhone = (new PhoneCheck())->goCheck();
        if($resultPhone['status'] == 0) return json(['status' => 0, 'msg' => $resultPhone['msg']]);

        $resultCode = (new CodeCheck())->goCheck();
        if($resultCode['status'] == 0) return json(['status' => 0, 'msg' => $resultCode['msg']]);

        $resultPwd = (new PwdCheck())->goCheck();
        if($resultPwd['status'] == 0) return json(['status' => 0, 'msg' => $resultPwd['msg']]);

        $resultPassword = (new PasswordCheck())->goCheck();
        if($resultPassword['status'] == 0) return json(['status' => 0, 'msg' => $resultPassword['msg']]);

        // 手机号
        $USER = new UserModel();
        $hasUser = $USER::findUser(['user_phone' => $phone]);
        if($hasUser) return json(['status' => 0, 'msg' => '该手机号已注册']);

        // 验证码
        $PHONECODE = new PhoneCodeModel();
        $yzm = $PHONECODE::findCode(['phone' => $phone]);
        $check = $this->checkPhoneCode($code, $yzm);
        if($check['status'] != 200) return json($check);

        // 密码
        if($password != $pwd) return json(['status' => 0, 'msg' => '两次输入的密码不一致']);

        $insert = [
            'user_phone' => $phone,
            'user_password' => md5($pwd),
            'user_time' => createTime()
        ];
        $res = $USER::insertUser($insert);
        if($res){
            $PHONECODE::updateCode(['phone' => $phone], ['status' => 1]);
            return json(['status' => 200, 'msg' => $this->doSuccess]);
        }else{
            return json(['status' => 0, 'msg' => $this->systemErr]);
        }

    }

    /**
     * 验证码登录
     * phone      手机号
     * code       验证码
     * @return \think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function codeLogin(){
        $phone = input('phone');
        $code = input('code');

        $resultPhone = (new PhoneCheck())->goCheck();
        if($resultPhone['status'] == 0) return json(['status' => 0, 'msg' => $resultPhone['msg']]);

        $resultCode = (new CodeCheck())->goCheck();
        if($resultCode['status'] == 0) return json(['status' => 0, 'msg' => $resultCode['msg']]);

        // 验证码
        $PHONECODE = new PhoneCodeModel();
        $yzm = $PHONECODE::findCode(['phone' => $phone]);
        $check = $this->checkPhoneCode($code, $yzm);
        if($check['status'] != 200) return json($check);

        // 手机号
        $USER = new UserModel();
        $hasUser = $USER::findUser(['user_phone' => $phone]);
        if(!$hasUser){
            return json(['status' => 0, 'msg' => '该手机号未注册']);
        } else{
            if($hasUser['user_status'] != 1){
                return json(['status' => 0, 'msg' => '该用户状态异常']);
            }
        }

        $update = ['user_last_login' => createTime()];
        $res = $USER::updateUser(['user_id' => $hasUser['user_id']], $update);
        if($res){
            $PHONECODE::updateCode(['phone' => $phone], ['status' => 1]);
            return json(['status' => 200, 'msg' => $hasUser]);
        }else{
            return json(['status' => 0, 'msg' => $this->systemErr]);
        }
    }

    /**
     * 账号密码登录
     * phone     手机号
     * pwd       密码
     * @return \think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function passwordLogin(){
        $phone = input('phone');
        $pwd = input('pwd');

        $resultPhone = (new PhoneCheck())->goCheck();
        if($resultPhone['status'] == 0) return json(['status' => 0, 'msg' => $resultPhone['msg']]);

        $resultPwd = (new PwdCheck())->goCheck();
        if($resultPwd['status'] == 0) return json(['status' => 0, 'msg' => $resultPwd['msg']]);

        // 手机号
        $USER = new UserModel();
        $hasUser = $USER::findUser(['user_phone' => $phone]);
        if(!$hasUser){
            return json(['status' => 0, 'msg' => '该手机号未注册']);
        } else{
            if($hasUser['user_status'] != 1){
                return json(['status' => 0, 'msg' => '该用户状态异常']);
            }else{
                if($hasUser['user_password'] != md5($pwd)){
                    return json(['status' => 0, 'msg' => '密码错误']);
                }
            }
        }

        $update = ['user_last_login' => createTime()];
        $res = $USER::updateUser(['user_id' => $hasUser['user_id']], $update);
        if($res){
            return json(['status' => 200, 'msg' => $hasUser]);
        }else{
            return json(['status' => 0, 'msg' => $this->systemErr]);
        }
    }

    /**
     * 忘记密码
     * phone      手机号
     * code       验证码
     * pwd        密码
     * password   确认密码
     * @return \think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function forgetPassword(){
        $phone = input('phone');
        $code = input('code');
        $pwd = input('pwd');
        $password = input('password');

        $resultPhone = (new PhoneCheck())->goCheck();
        if($resultPhone['status'] == 0) return json(['status' => 0, 'msg' => $resultPhone['msg']]);

        $resultCode = (new CodeCheck())->goCheck();
        if($resultCode['status'] == 0) return json(['status' => 0, 'msg' => $resultCode['msg']]);

        $resultPwd = (new PwdCheck())->goCheck();
        if($resultPwd['status'] == 0) return json(['status' => 0, 'msg' => $resultPwd['msg']]);

        $resultPassword = (new PasswordCheck())->goCheck();
        if($resultPassword['status'] == 0) return json(['status' => 0, 'msg' => $resultPassword['msg']]);

        // 手机号
        $USER = new UserModel();
        $hasUser = $USER::findUser(['user_phone' => $phone]);
        if(!$hasUser) return json(['status' => 0, 'msg' => '该手机号未注册']);

        // 验证码
        $PHONECODE = new PhoneCodeModel();
        $yzm = $PHONECODE::findCode(['phone' => $phone]);
        $check = $this->checkPhoneCode($code, $yzm);
        if($check['status'] != 200) return json($check);

        // 密码
        if($password != $pwd) return json(['status' => 0, 'msg' => '两次输入的密码不一致']);

        $update = [
            'user_password' => md5($pwd),
            'user_update_time' => createTime()
        ];
        $res = $USER::updateUser(['user_id' => $hasUser['user_id']], $update);
        if($res){
            $PHONECODE::updateCode(['phone' => $phone], ['status' => 1]);
            return json(['status' => 200, 'msg' => $this->doSuccess]);
        }else{
            return json(['status' => 0, 'msg' => $this->systemErr]);
        }
    }

    /**
     * 修改密码
     * user_id     用户ID
     * phone       手机号
     * code        验证码
     * pwd         密码
     * password    确认密码
     * @return \think\response\Json
     */
    public function changePassword(){
        $user_id = input('user_id');
        $phone = input('phone');
        $code = input('code');
        $pwd = input('pwd');
        $password = input('password');

        $resultUserId = (new UserIdCheck())->goCheck();
        if($resultUserId['status'] == 0) return json(['status' => 0, 'msg' => $resultUserId['msg']]);

        $resultPhone = (new PhoneCheck())->goCheck();
        if($resultPhone['status'] == 0) return json(['status' => 0, 'msg' => $resultPhone['msg']]);

        $resultCode = (new CodeCheck())->goCheck();
        if($resultCode['status'] == 0) return json(['status' => 0, 'msg' => $resultCode['msg']]);

        $resultPwd = (new PwdCheck())->goCheck();
        if($resultPwd['status'] == 0) return json(['status' => 0, 'msg' => $resultPwd['msg']]);

        $resultPassword = (new PasswordCheck())->goCheck();
        if($resultPassword['status'] == 0) return json(['status' => 0, 'msg' => $resultPassword['msg']]);

        // 密码
        if($password != $pwd) return json(['status' => 0, 'msg' => '两次输入的密码不一致']);

        // 手机号
        $USER = new UserModel();
        $hasUser = $USER::findUser(['user_phone' => $phone]);
        if(!$hasUser) return json(['status' => 0, 'msg' => '该手机号未注册']);

        // 验证码
        $PHONECODE = new PhoneCodeModel();
        $yzm = $PHONECODE::findCode(['phone' => $phone]);
        $check = $this->checkPhoneCode($code, $yzm);
        if($check['status'] != 200) return json($check);

        $update = [
            'user_password'    => md5($pwd),
            'user_update_time' => createTime()
        ];
        $res = $USER::updateUser(['user_id' => $user_id], $update);
        if($res){
            $PHONECODE::updateCode(['phone' => $phone], ['status' => 1]);
            return json(['status' => 200, 'msg' => $this->doSuccess]);
        }else{
            return json(['status' => 0, 'msg' => $this->systemErr]);
        }
    }

    /**
     * 验证码状态判断
     * @param $code      验证码
     * @return array
     */
    private function checkPhoneCode($code, $yzm){
        if(!$yzm) return ['status' => 0, 'msg' => '请先发送验证码'];
        if($yzm['status'] == 1) return ['status' => 0, 'msg' => '验证码已使用'];
        $now = time();
        if($now - $yzm['time'] > 300) return ['status' => 0, 'msg' => '验证码失效'];
        if($code != $yzm['code']) return ['status' => 0, 'msg' => '验证码错误'];
        return ['status' => 200, 'msg' => true, 'id' => $yzm['id']];
    }
}